﻿using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using Urs.Admin.Models.Stores;
using Urs.Data.Domain.Stores;
using Urs.Data.Domain.Users;
using Urs.Services.Localization;
using Urs.Services.Security;
using Urs.Services.Stores;
using Urs.Services.Users;
using Urs.Framework.Controllers;
using Urs.Framework.Kendoui;

namespace Urs.Admin.Controllers
{
    [AdminAuthorize]
    public partial class GoodsReviewController : BaseAdminController
    {
        #region Fields

        private readonly IGoodsService _goodsService;
        private readonly ILocalizationService _localizationService;
        private readonly IPermissionService _permissionService;
        private readonly IUserService _userService;

        #endregion Fields

        #region Constructors

        public GoodsReviewController(IGoodsService goodsService,
            IUserService userService,
            ILocalizationService localizationService, IPermissionService permissionService)
        {
            this._userService = userService;
            this._goodsService = goodsService;
            this._localizationService = localizationService;
            this._permissionService = permissionService;
        }

        #endregion

        #region Utilities

        [NonAction]
        protected void PrepareGoodsReviewModel(GoodsReviewModel model,
            GoodsReview goodsReview, User user, bool excludeProperties, bool formatReviewText)
        {
            if (model == null)
                throw new ArgumentNullException("model");

            if (goodsReview == null)
                throw new ArgumentNullException("goodsReview");

            var goods = _goodsService.GetGoodsById(goodsReview.GoodsId);
            if (goods == null)
                throw new ArgumentNullException("goods");

            model.Id = goodsReview.Id;
            model.GoodsId = goodsReview.GoodsId;
            model.GoodsName = goods.Name;
            model.UserId = goodsReview.UserId;
            model.UserInfo = user.IsRegistered() ? user.GetFullName() : _localizationService.GetResource("Admin.Users.Guest");
            model.Rating = goodsReview.Rating;
            model.CreateTime = goodsReview.CreateTime;
            if (!excludeProperties)
            {
                model.Title = goodsReview.Title;
                if (formatReviewText)
                    model.ReviewText = Core.Html.HtmlHelper.FormatText(goodsReview.ReviewText, false, true, false, false, false, false);
                else
                    model.ReviewText = goodsReview.ReviewText;
            }
        }

        #endregion

        #region Methods

        //list
        public IActionResult Index()
        {
            return RedirectToAction("List");
        }

        public IActionResult List()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            var model = new GoodsReviewListModel();
            return View(model);
        }

        [HttpPost]
        public IActionResult ListJson(PageRequest command, GoodsReviewListModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            DateTime? createdOnFromValue = (model.CreateTimeFrom == null) ? null
                            : (DateTime?)model.CreateTimeFrom.Value;

            DateTime? createdToFromValue = (model.CreateTimeTo == null) ? null
                            : (DateTime?)model.CreateTimeTo.Value.AddDays(1);

            var list = _goodsService.GetGoodsReviews(model.SearchGoodsId, null, null, model.IsApproved,
                createdOnFromValue, createdToFromValue,command.Page-1,command.Limit);

            var users = _userService.GetUsersByIds(list.Select(q => q.UserId).ToArray());

            var result = new ResponseResult
            {
                data = list.Select(x =>
                {
                    var c = users.FirstOrDefault(q => q.Id == x.UserId);
                    var m = new GoodsReviewModel();
                    PrepareGoodsReviewModel(m, x, c, false, true);
                    return m;
                }),
                count = list.Count,
            };
            return Json(result);
        }


        public IActionResult Add(int userId, string reviewText, int goodsId, int rating)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            var goods = _goodsService.GetGoodsById(goodsId);
            if (goods == null)
                throw new ArgumentException("No goodsfound with the id");

            var goodsReview = new GoodsReview()
            {
                UserId = userId,
                GoodsId = goodsId,
                ReviewText = reviewText,
                Rating = rating,
                CreateTime = DateTime.Now
            };
            _goodsService.InsertGoodsReview(goodsReview);
            //update goods totals
            _goodsService.UpdateGoodsReviewTotals(goods);

            return Json(new { Result = true });
        }

        //edit
        public IActionResult Edit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();
            var model = new GoodsReviewModel();
            var goodsReview = _goodsService.GetGoodsReviewById(id);
            if (goodsReview == null)
            {
                return View(model);
            }
            else
            {
                var user = _userService.GetUserById(goodsReview.UserId);
                PrepareGoodsReviewModel(model, goodsReview, user, false, false);
            }
            return View(model);


        }

        [HttpPost]
        public IActionResult Edit(GoodsReviewModel model, bool continueEditing, int userId, string reviewText, int goodsId, int rating)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            var goods = _goodsService.GetGoodsById(goodsId);
            if (goods == null)
                throw new ArgumentException("No goodsfound with the id");

            var user = _userService.GetUserById(userId);

            var goodsReview = _goodsService.GetGoodsReviewById(model.Id);
            if (goodsReview == null)
            {

                var goodsReviews = new GoodsReview()
                {
                    UserId = userId,
                    GoodsId = goodsId,
                    ReviewText = reviewText,
                    Rating = rating,
                    CreateTime = DateTime.Now
                };

                _goodsService.InsertGoodsReview(goodsReviews);
                //update goods totals
                _goodsService.UpdateGoodsReviewTotals(goods);
            }
            else
            {
                if (ModelState.IsValid)
                {
                    goodsReview.Title = model.Title;
                    goodsReview.ReviewText = model.ReviewText;
                    _goodsService.UpdateGoodsReview(goodsReview);

                    //update goods totals
                    _goodsService.UpdateGoodsReviewTotals(goods);
                }
            }
            PrepareGoodsReviewModel(model, goodsReview, user, true, false);
            return Json(new { success = 1 });
        }

        //delete
        [HttpPost]
        public IActionResult Delete(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            var goodsReview = _goodsService.GetGoodsReviewById(id);
            if (goodsReview == null)
                //No goods review found with the specified id
                return RedirectToAction("List");

            var goods = _goodsService.GetGoodsById(goodsReview.GoodsId);
            if (goods == null)
                throw new ArgumentNullException("goods");

            _goodsService.UpdateGoodsReview(goodsReview);
            //update goods totals
            _goodsService.UpdateGoodsReviewTotals(goods);

            return RedirectToAction("List");
        }

        [HttpPost]
        public IActionResult ApproveSelected(ICollection<int> selectedIds)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            if (selectedIds != null)
            {
                foreach (var id in selectedIds)
                {
                    var goodsReview = _goodsService.GetGoodsReviewById(id);
                    if (goodsReview != null)
                    {
                        var goods = _goodsService.GetGoodsById(goodsReview.GoodsId);
                        if (goods != null)
                        {
                            _goodsService.UpdateGoodsReview(goodsReview);
                            //update goods totals
                            _goodsService.UpdateGoodsReviewTotals(goods);
                        }
                    }
                }
            }

            return Json(new { Result = true });
        }

        [HttpPost]
        public IActionResult DisapproveSelected(ICollection<int> selectedIds)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageGoodsReviews))
                return HttpUnauthorized();

            if (selectedIds != null)
            {
                foreach (var id in selectedIds)
                {
                    var goodsReview = _goodsService.GetGoodsReviewById(id);
                    if (goodsReview != null)
                    {
                        var goods = _goodsService.GetGoodsById(goodsReview.GoodsId);
                        if (goods != null)
                        {
                            _goodsService.UpdateGoodsReview(goodsReview);
                            //update goods totals
                            _goodsService.UpdateGoodsReviewTotals(goods);
                        }
                    }
                }
            }

            return Json(new { Result = true });
        }

        public IActionResult GoodsSearchAutoComplete(string term)
        {
            const int searchTermMinimumLength = 3;
            if (String.IsNullOrWhiteSpace(term) || term.Length < searchTermMinimumLength)
                return Content("");

            //goods
            const int goodsNumber = 15;
            var list = _goodsService.SearchGoodss(out IList<int> filterableGoodsParameterOptionIds,
                orderBy: GoodsSortingEnum.Position, pageSize: goodsNumber, showHidden: true);

            var result = (from p in list
                          select new
                          {
                              label = p.Name,
                              goodsid = p.Id
                          })
                .ToList();
            return Json(result);
        }


        #endregion
    }
}
